/*
 * KRPolicyOWL.java
 *
 * Created on December 12, 2003, 1:15 PM
 */

package abdn.graph.growl;

import java.io.File;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import abdn.graph.ontobrowser.ESDOntoBrowser;
import abdn.graph.ontobrowser.KRPolicy;
import abdn.graph.ontobrowser.KRPolicyWrite;
import abdn.graph.ontobrowser.OBRelationNode;
import org.semanticweb.owl.impl.model.OWLConnectionImpl;
import org.semanticweb.owl.io.abstract_syntax.Renderer;
import org.semanticweb.owl.io.owl_rdf.OWLRDFErrorHandler;
import org.semanticweb.owl.io.owl_rdf.OWLRDFParser;
import org.semanticweb.owl.model.OWLOntology;
import org.xml.sax.SAXException;

import com.touchgraph.graphlayout.TGPanel;
import abdn.CleanONTO.util.*;
//import abdn.taxon.data.PropertyVector;*/

/**
 *
 * @author skrivov
 */
public class KRPolicyOWL
    implements KRPolicy, KRPolicyWrite {

  public static final int OWLRDF = 0;
  public static final int Abstract = 1;

  TGPanel tgPanel;

  //GraphEltSet graphEltSet;
  ESDOntoBrowser esdOntoBrowser;

  OWLRDFParser parser = null;

  OWLOntology currentOntology = null;

  BuildGraphVisitor visitor = null;

  //MyRenderer renderer = null;

  Set includeOntologies = null;

  OWLMetadata metadata;

  //I am not sure if we need this
  //private Map known;
  //private List shortNames;
  //	private Set allURIs;

  boolean multiplePropertyCopies = false;

  public boolean processIncludeOntologies = true;

  //WordNetData wordData;
  WordNetDictionary wordData;

  /** Creates a new instance of KRPolicyOWL */
  public KRPolicyOWL() {
    //System.setProperty("org.semanticweb.owl.util.OWLConnection",
    // "org.semanticweb.owl.impl.model.OWLConnectionImpl.class");
    metadata = new OWLMetadata();
    metadata.setDefaults();
  }

  /**
   *
   * @param w
   */
  public KRPolicyOWL(WordNetDictionary w) {
    metadata = new OWLMetadata();
    metadata.setDefaults();
    wordData = w;
  }

  public void setOBPointer(ESDOntoBrowser ob) {
    esdOntoBrowser = ob;
    tgPanel = esdOntoBrowser.getTGPanel();
    //graphEltSet = tgPanel.getCompleteEltSet();
  }

  public void read(String fileName) throws Exception {
    read(fileName, null);
  }

  public void read(URL xmlURL) throws Exception {
    read(xmlURL, null);
  }

  public void read(String fileName, Thread afterReading) throws Exception {
    URI uri = null;
    File f = new File(fileName);
    /*
     * try { uri =f.toURI(); } catch (URISyntaxException e) {
     * e.printStackTrace(); }
     */
    read(f.toURI(), afterReading);

  }

  /**
   * Reads data from a URL <tt>url</tt>, executing the
   * <tt>afterReading</tt> Thread after the data is read in.
   */
  public void read(URL url, Thread afterReading) throws Exception {
    URI uri = null;
    try {
      uri = new URI(url.toString());
    }
    catch (URISyntaxException e) {
      e.printStackTrace();
    }
    read(uri, afterReading);
  }

  public void read(URI uri, Thread afterReading) throws Exception {
    //parser = new OWLRDFParser();
    OWLConnectionImpl conn = new OWLConnectionImpl();
    parser.setConnection(conn);
    OWLRDFErrorHandler handler = new OWLRDFErrorHandler() {
      public void owlFullConstruct(int code, String message) throws
          SAXException {
        System.out.println("owlFullConstruct: " + message);
      }

      public void error(String message) throws SAXException {
        System.out.println("ERROR: " + message);
      }

      public void warning(String message) throws SAXException {
        System.out.println("WARNING: " + message);
      }
    };
    parser.setOWLRDFErrorHandler(handler);
    OWLOntology ontology = parser.parseOntology(uri);
    currentOntology = ontology;

    OWLtoGraph owl2g = new OWLtoGraph(esdOntoBrowser, wordData);
    //owl2g.buildGraphEltSet(ontology, parser.getPrefixMap());
    metadata = owl2g.getMetadata();

    if (afterReading != null) {
      afterReading.start();
    }
  }

  /*public void read(EntityVector entities, EntityRelationVector entitiesRelation, Thread afterReading) throws
      Exception {

    OWLtoGraph owl2g = new OWLtoGraph(esdOntoBrowser, wordData);
    owl2g.buildOntology(entities, entitiesRelation, optimization);

    if (afterReading != null) {
      afterReading.start();
    }
  }*/
  /**
   *
   * @param e
   * @param er1
   * @param er2
   * @param o
   * @param afterReading
   * @throws java.lang.Exception
   */
  public void read(EntityVector e, EntityRelationVector er1, EntityRelationVector er2, boolean o, Thread afterReading) throws Exception {
    OWLtoGraph owl2g = new OWLtoGraph(esdOntoBrowser);
    owl2g.buildOntology(e, er1, er2, o);
    if (afterReading != null) {
      afterReading.start();
    }
  }

  public void write(OutputStream out, int format) throws Exception {
    /*String uri;
    GraphToOWL g = new GraphToOWL(esdOntoBrowser);
    OWLOntology onto = g.buildOWLOntology(getBaseURI());

    if (onto != null) {
      OutputStreamWriter w = new OutputStreamWriter(out);
      if (format == OWLRDF) {
        MyRenderer r = new MyRenderer(metadata);
        r.renderOntology(onto, w);
      }
      else {
        Renderer r = new Renderer();
        r.renderOntology(onto, w);
      }
      w.flush();
    }*/
  }

  public String getBaseURI() {
    return metadata.getBaseURI().toString();
  }

  public void setBaseURI(String s) throws URISyntaxException {
    metadata.setBaseURI(new URI(s));
  }

  /*
   * private void generateShortNames() { // Generates a list of namespaces.
   * shortNames = new ArrayList(); known = new HashMap();
   * known.put(OWLVocabularyAdapter.OWL, "owl");
   * known.put(RDFVocabularyAdapter.RDF, "rdf");
   * known.put(RDFSVocabularyAdapter.RDFS, "rdfs");
   * known.put(XMLSchemaSimpleDatatypeVocabulary.XS, "xsd");
   *
   * for (Iterator it = allURIs.iterator(); it.hasNext();) { try { URI uri =
   * (URI) it.next(); if (uri.getFragment() != null) { String ssp = new URI(
   * uri.getScheme(), uri.getSchemeSpecificPart(), null) .toString(); // Trim
   * off the fragment bit if necessary if (!ssp.endsWith("#")) { ssp = ssp +
   * "#"; } if (!known.keySet().contains(ssp) && !shortNames.contains(ssp)) {
   * shortNames.add(ssp); } } } catch (URISyntaxException ex) { } } }
   */

  public static void addLabelPrefix(OBRelationNode rn, String lbl) {
    String label;
    switch (rn.relationSubCategory) {

      case RenderGrowl.REL_OBJECT_PROPERTY_RESTRICT_SOME:
      case RenderGrowl.REL_DATA_PROPERTY_RESTRICT_SOME:
        label = "\u2203:" + lbl;
        break;
      case RenderGrowl.REL_OBJECT_PROPERTY_RESTRICT_ALL:
      case RenderGrowl.REL_DATA_PROPERTY_RESTRICT_ALL:
        label = "\u2200:" + lbl;
        ;
        break;
      case RenderGrowl.REL_OBJECT_PROPERTY_RESTRICT_CARD:
      case RenderGrowl.REL_DATA_PROPERTY_RESTRICT_CARD:
        if (rn.minCardinality == rn.maxCardinality
            && rn.maxCardinality > -1) {
          label = String.valueOf(rn.maxCardinality) + ':' + lbl;
        }
        else if (rn.maxCardinality > 0 && rn.minCardinality > 0) {
          label =
              "["
              + String.valueOf(rn.minCardinality)
              + ","
              + String.valueOf(rn.maxCardinality)
              + "]:"
              + lbl;
        }
        else if (rn.minCardinality > 0 && rn.maxCardinality == -1) {
          label =
              "\u2265"
              + String.valueOf(rn.minCardinality)
              + ':'
              + lbl;
        }
        else if (rn.minCardinality <= 0 && rn.maxCardinality > 0) {
          label =
              "\u2264"
              + String.valueOf(rn.maxCardinality)
              + ':'
              + lbl;
        }
        else {
          label = lbl;
        }
        break;
        /*
         * case RenderGrowl.REL_DATA_PROPERTY_RESTRICT_VALUE : case
         * RenderGrowl.REL_OBJECT_PROPERTY_RESTRICT_VALUE : case
         * RenderGrowl.REL_OBJECT_PROPERTY_VALUE : case
         * RenderGrowl.REL_DATA_PROPERTY_VALUE : case
             * RenderGrowl.REL_OBJECT_PROPERTY : case RenderGrowl.REL_DATA_PROPERTY :
         * case RenderGrowl.REL_SUBCLASS : case RenderGrowl.REL_INSTANCE : case
             * RenderGrowl.REL_ARE_EQUIVALENT : case RenderGrowl.REL_ARE_SAME : case
         * RenderGrowl.REL_ARE_DIFFERENT : case RenderGrowl.REL_ARE_DISJOINT :
         * case RenderGrowl.REL_IS_SAME_AS : case RenderGrowl.REL_ONE_OF :
      */
      default: {
        //label = lbl;
        rn.setLabel(lbl);
        return;
      }

    }

    rn.setNodeLabel(label);
  }

  public static String stripLabel(String lbl) {
    if (lbl == null) {
      return null;
    }
    //String lbl = rn.getLabel();
    int pos = lbl.indexOf(':');
    if (pos > 0 && !Character.isLetter(lbl.charAt(0))) {
      return lbl.substring(pos + 1);
    }
    return lbl;
  }

  public static String stripNamespace(String lbl) {
    if (lbl == null) {
      return null;
    }
    //String lbl = rn.getLabel();
    int pos = lbl.indexOf(':');
    if (pos > 0 && Character.isLetter(lbl.charAt(0))) {
      return lbl.substring(pos + 1);
    }
    return lbl;
  }
  /**
   * @return an OWLOntology
   * @see OWLOntology
   */
  public OWLOntology getOntology() {
    return currentOntology;
  }
  /**
   * @return a set of imported ontologies
   */
  public Set getIncludeOntologies() {
    return includeOntologies;
  }
  /**
   * Method getMetadata
   * @return a OWLMetadata
   * @see OWLMetadata
   */
  public OWLMetadata getMetadata() {
    return metadata;
  }

  class MyRenderer extends org.semanticweb.owl.io.owl_rdf.Renderer {
    OWLMetadata metadata;

    MyRenderer(OWLMetadata m) {
      super();
      metadata = m;
    }

    public String shortForm(URI uri) {
      return metadata.shortForm(uri);
    }

    public boolean isLocal(URI uri) {
      String s = metadata.getPrefixOfFullURI(uri);
      return s == null || s.length() == 0;
    }

  }

}
